package com.copm.ifm.servers.sys.service.impl.tenant;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.copm.ifm.base.api.pojo.BasePO;
import com.copm.ifm.base.api.pojo.PageDTO;
import com.copm.ifm.base.api.pojo.PageVO;
import com.copm.ifm.base.api.util.CollectionUtils;
import com.copm.ifm.base.basic.ServiceResponse;
import com.copm.ifm.base.basic.constant.DbConstants;
import com.copm.ifm.base.basic.enums.DictCodeEnum;
import com.copm.ifm.base.basic.enums.ResponseCodeEnum;
import com.copm.ifm.base.basic.exception.ServiceException;
import com.copm.ifm.base.basic.util.AuthUtils;
import com.copm.ifm.base.service.mp.page.PageProxy;
import com.copm.ifm.servers.sys.dto.SysProjectDTO;
import com.copm.ifm.servers.sys.dto.SysTenantAddDTO;
import com.copm.ifm.servers.sys.dto.SysTenantPageDTO;
import com.copm.ifm.servers.sys.dto.SysTenantUpdateDTO;
import com.copm.ifm.servers.sys.entity.SysBusinessType;
import com.copm.ifm.servers.sys.entity.SysTenant;
import com.copm.ifm.servers.sys.entity.SysTenantDetail;
import com.copm.ifm.servers.sys.mapper.tenant.SysTenantDetailMapper;
import com.copm.ifm.servers.sys.mapper.tenant.SysTenantMapper;
import com.copm.ifm.servers.sys.mapping.SysTenantMapping;
import com.copm.ifm.servers.sys.service.impl.project.SysProjectServiceImpl;
import com.copm.ifm.servers.sys.service.process.SysDictService;
import com.copm.ifm.servers.sys.service.tenant.SysTenantService;
import com.copm.ifm.servers.sys.service.type.SysBusinessTypeService;
import com.copm.ifm.servers.sys.vo.SysProjectVO;
import com.copm.ifm.servers.sys.vo.SysTenantDetailVO;
import com.copm.ifm.servers.sys.vo.SysTenantVO;
import com.google.common.base.Joiner;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统租户表 服务实现类
 *
 * @author zzf
 * @since 2020-12-14
 */
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements SysTenantService {

    @Resource
    SysTenantMapper sysTenantMapper;

    @Resource
    SysTenantDetailMapper detailMapper;

    @Resource
    SysProjectServiceImpl sysProjectServiceImpl;

    @Resource
    SysBusinessTypeService sysBusinessTypeService;

    @Resource
    SysTenantService sysTenantService;

    @Resource
    SysDictService sysDictService;

    private static final String BUSINESS_TYPE = "BUSINESS_TYPE";

    @Override
    public PageVO<SysTenantVO> selectForPage(PageDTO<SysTenantPageDTO> pageDTO) {
        if ("name".equals(pageDTO.getSortName())) {
            pageDTO.setSortName("CONVERT( tenantName USING gbk )");
        }
        PageVO<SysTenantVO> proxy = PageProxy.proxy(baseMapper::selectForPage, pageDTO);
        List<SysTenantVO> record = proxy.getRecords();
        ServiceResponse<List<SysTenantVO>> success = new ServiceResponse<>(record, ResponseCodeEnum.SUCCESS);
        proxy.setRecords(success.getData());

        List<SysTenantVO> records = proxy.getRecords();
        records.forEach(s -> {
            StringBuilder sb = new StringBuilder();
            s.getType().forEach(x -> sb.append(sysDictService.getName(DictCodeEnum.ORG_TYPE.getCode(), x)).append(","));
            if (sb.length() > 0) {
                s.setTypeName(sb.substring(0, sb.length() - 1));
            }
        });
        return proxy;
    }

    @Override
    public SysTenant selectById(Long id) {
        return sysTenantMapper.selectById(id);
    }

    /**
     * 新增
     * 1.校验只能存在1个系统管理方，无论租户是否有效
     * 2.校验编号唯一性，无论租户是否有效
     */
    @Override
    public void add(SysTenantAddDTO addDTO) {
        if (addDTO.getSysAdmin().equals(DbConstants.DEFAULT_YES) && this.getSysAdminId() != null) {
            throw new ServiceException("已存在系统管理方，请确认后重新提交。");
        }
        if (this.checkCode(addDTO.getCode()) != null) {
            throw new ServiceException("编号已存在，请确认后重新提交。");
        }
        SysTenant sysTenant = SysTenantMapping.INSTANCE.addDTO2PO(addDTO);
        sysTenant.setCreateBy(AuthUtils.getCurrentUserId());
        sysTenant.setUpdateBy(AuthUtils.getCurrentUserId());
        sysTenant.setCreateTime(new Date());
        sysTenant.setUpdateTime(new Date());
        baseMapper.insert(sysTenant);

        SysTenantDetail detail = SysTenantMapping.INSTANCE.addDTO2Deatil(addDTO);
        detail.setTenantId(sysTenant.getId());
        detailMapper.insert(detail);
    }

    @Override
    public void updateDetail(SysTenantUpdateDTO updateDTO) {
        SysTenant sysTenant = SysTenantMapping.INSTANCE.updateDTO2PO(updateDTO);
        sysTenant.setUpdateBy(AuthUtils.getCurrentUserId());
        sysTenant.setUpdateTime(new Date());
        baseMapper.updateById(sysTenant);

        SysTenantDetail detail = SysTenantMapping.INSTANCE.updateDTO2Detail(updateDTO);
        detailMapper.update(detail, new LambdaUpdateWrapper<SysTenantDetail>()
                .eq(SysTenantDetail::getTenantId, updateDTO.getId()));
    }

    @Override
    public int updateDeleted(Long id) {
        SysTenant sysTenant = new SysTenant();
        sysTenant.setId(id);
        sysTenant.setDeleted(DbConstants.DEFAULT_YES);
        return sysTenantMapper.updateById(sysTenant);
    }

    @Override
    public SysTenantVO selectVOById(Long id) {
        return sysTenantMapper.selectVOById(id);
    }

    @Override
    public Long checkCode(String code) {
        SysTenant sysTenant = baseMapper.selectOne(new LambdaQueryWrapper<SysTenant>()
                .eq(SysTenant::getCode, code)
                .eq(BasePO::getDeleted, DbConstants.DEFAULT_NO));
        return sysTenant != null ? sysTenant.getId() : null;
    }

    @Override
    public Long getSysAdminId() {
        Long sysAdminId = baseMapper.selectSysAdminId();
        return sysAdminId != null && !sysAdminId.equals(0L) ? sysAdminId : null;
    }

    @Override
    public SysTenantDetailVO getDetail(Long id) {
        return baseMapper.selectDetail(id);
    }

    @Override
    public List<SysTenant> selectAllTenant() {
        List<SysTenant> sysTenants = list(new LambdaQueryWrapper<SysTenant>()
                .eq(SysTenant::getEnabled, DbConstants.DEFAULT_YES)
                .eq(SysTenant::getDeleted, DbConstants.DEFAULT_NO));
        sysTenants.forEach(s -> s.setName(s.getName() + ": " + s.getCode()));
        return sysTenants;
    }

    @Override
    public PageVO<SysProjectVO> getProjectDetailPage(PageDTO<SysProjectDTO> pageDTO) {
        PageVO<SysProjectVO> proxy = sysProjectServiceImpl.selectTenantAuthForPage(pageDTO);
        //这里的businessType是对应项目中的业务类型权限
        List<SysProjectVO> sysProjectVO = proxy.getRecords();
        //多时间段的业务类型去重合集
        sysProjectVO.forEach(s -> {
            String businessType = s.getBusinessType();
            List<String> businessTypeList = CollectionUtils.removeDuplicateList(businessType);
            List<SysBusinessType> list = sysBusinessTypeService.list(new LambdaQueryWrapper<SysBusinessType>()
                    .in(SysBusinessType::getCode, businessTypeList)
                    .eq(SysBusinessType::getTenantId, s.getTenantId()));
            List<String> nameList = list.stream().map(SysBusinessType::getName).collect(Collectors.toList());
            String businessTypeName = Joiner.on(",").join(nameList);
            s.setBusinessType(businessTypeName);
        });
        return proxy;
    }

    @Override
    public void updateBusinessById(SysBusinessType entity) {
        entity.setUpdateBy(AuthUtils.getCurrentUserId());
        entity.setUpdateTime(new Date());
        sysBusinessTypeService.updateById(entity);
        SysTenant sysTenant = new SysTenant();
        sysTenant.setId(entity.getTenantId());
        sysTenant.setAllAuth(DbConstants.DEFAULT_NO);
        sysTenantMapper.updateById(sysTenant);
    }

    @Override
    public void selectAllByTenantId(Long tenantId) {
        List<SysBusinessType> sysBusinessTypeList = sysBusinessTypeService.selectByTenantId(tenantId);
        sysBusinessTypeList.forEach(s -> {
            s.setIsAuth(DbConstants.DEFAULT_YES);
            s.setUpdateBy(AuthUtils.getCurrentUserId());
            s.setUpdateTime(new Date());
        });
        sysBusinessTypeService.updateBatchById(sysBusinessTypeList);
        SysTenant sysTenant = new SysTenant();
        sysTenant.setId(tenantId);
        sysTenant.setAllAuth(DbConstants.DEFAULT_YES);
        sysTenantService.updateById(sysTenant);
    }

    @Override
    public List<SysBusinessType> listAllType(Long tenantId) {
        if (StringUtils.isEmpty(tenantId)) {
            return null;
        }
        List<SysBusinessType> sysBusinessTypes = sysBusinessTypeService.list(new LambdaQueryWrapper<SysBusinessType>()
                .eq(SysBusinessType::getTenantId, tenantId)
                .eq(SysBusinessType::getIsAuth, DbConstants.DEFAULT_YES)
                .eq(SysBusinessType::getDeleted, DbConstants.DEFAULT_NO));
        if (sysBusinessTypes.size() == 0) {
            return null;
        }
        return sysBusinessTypes;
    }

    @Override
    public List<SysTenant> listSupplier(Integer supplierType) {
        return sysTenantMapper.listSupplier(supplierType);
    }

}